package com.fengzai;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by  峰仔  on 2017-07-31
 */
@Mojo(name = "addVersion", defaultPhase = LifecyclePhase.PACKAGE)
public class AddVersionMojo extends AbstractMojo {

    /**
     * 当前build项目的路径
     */
    @Parameter(property = "project.build.directory")
    private String directory;
    /**
     * 当前build项目的名称
     */
    @Parameter(property = "project.build.finalName")
    private String finalName;
    /**
     * 默认匹配.html  和.jsp文件
     */
    @Parameter(defaultValue = "*.html,*.jsp")
    private List<String> resources;
    /**
     * 指定要添加版本号的资源后缀   默认.js  和.css文件
     */
    @Parameter(defaultValue = "js,css")
    private List<String> includs;
    /**
     * 指定输出目录  默认为${directory}-${finaName}-${version}.war
     */
    @Parameter
    private String outDirectory;

    /**
     * 版本号 没有则使用当前系统时间戳
     */
    @Parameter
    private String version;
    /**
     * 文件打包格式
     */
    @Parameter(property = "project.packaging")
    private String packaging;

    public AddVersionMojo() {
    }


    public void execute() throws MojoExecutionException, MojoFailureException {
//        System.out.println(directory);
//        System.out.println(finalName);
//        System.out.println(includs);
        //不是war不处理
        if (!"war".equals(packaging)) {
            return;
        }

        checkVersion();
        checkOutDirectory();
        foreach(null);
        outWar();

    }

    /**
     * 遍历文件
     */

    private void foreach(File file) {
        file = file != null ? file : new File(directory + "/" + finalName);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File f : files) {
                    foreach(f);
                }
            } else {
                // fileNames.add(file);
                //校验文件是否需要加版本号
                if (isAddVersionFile(file)) {
                    addVersion(file);
                }
            }
        }
    }

    /**
     * 检查版本号
     */
    private void checkVersion() {
        version = version == null ? System.currentTimeMillis() + "" : version;
    }

    /**
     * 检查输出目录
     */
    private void checkOutDirectory() {
        outDirectory = outDirectory == null ? directory : outDirectory;
    }

    /**
     * 匹配文件是否是需要添加版本号的文件
     *
     * @param file
     * @return
     */
    private boolean isAddVersionFile(File file) {
        for (String includ : resources) {
            Pattern pattern;
            if (includ.endsWith(".html") || includ.endsWith(".htm") || includ.endsWith(".jsp")) {
                pattern = Pattern.compile(includ.replace("*", "[a-zA-Z0-9/.:_\\-]*"));
            } else {
                pattern = Pattern.compile(includ);
            }
            Matcher matcher = pattern.matcher(file.getName().replaceAll("\\\\", "/"));
            if (matcher.matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 添加版本号
     *
     * @param file
     */

    private void addVersion(File file) {
        //把 文件重命名
        File temp = new File("temp");
        if (temp.exists()) {
            temp.delete();
        }
        file.renameTo(temp);
        try (

                BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(temp)));
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
        ) {
            while (reader.ready()) {
                String line = reader.readLine();
//                System.out.println(line);
                for (String includ : includs) {
                    if (line.contains("." + includ + "?")) {
                        line = replace(line, "." + includ + "?");
                        break;
                    } else if (line.contains("." + includ)) {
                        line = replace(line, "." + includ);
                        break;
                    }
                }
                writer.write(line + "\n");
            }
            //把临时文件清除
            temp.delete();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 替换 添加版本号
     *
     * @param targer
     * @param param
     * @return
     */
    private String replace(String targer, String param) {
        int index = targer.lastIndexOf(param);
        String s1 = targer.substring(0, index);
        String s2 = targer.substring(index + param.length());
        return s1 + param.replace("?", "") + "?v=" + version + s2;

    }

    /**
     * 输出成war
     */
    private void outWar() {
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(outDirectory + "/" + finalName + "-" + version + ".war"))) {
            File source = new File(directory + "/" + finalName);
            for (File file : source.listFiles()) {
                addWar(zipOutputStream, file, "");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向war中写如文件
     *
     * @param zipOutputStream
     * @param file
     * @param path
     */
    private void addWar(ZipOutputStream zipOutputStream, File file, String path) {
        if (file.isDirectory()) {
            String src = path + file.getName() + "/";
            try {
                zipOutputStream.putNextEntry(new ZipEntry(src));
            } catch (IOException e) {
                e.printStackTrace();
            }
            file.listFiles();
            for (File f : file.listFiles()) {
                addWar(zipOutputStream, f, src);
            }
        } else {
            try (
                    BufferedInputStream bfin = new BufferedInputStream(new FileInputStream(file))
            ) {
                zipOutputStream.putNextEntry(new ZipEntry(path + file.getName()));
                int length = 0;
                byte[] bytes = new byte[2048];
                while ((length = (bfin.read(bytes, 0, bytes.length))) != -1) {
                    zipOutputStream.write(bytes, 0, length);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) {
        AddVersionMojo addVersionMojo = new AddVersionMojo();
        String css = addVersionMojo.replace("<link href=\"../css/login.css\" />", "css");
        System.out.println(css);
//        addVersionMojo.resources = new ArrayList<>();
//        addVersionMojo.resources.add("*.html");
//        addVersionMojo.resources.add("*.jsp");
//        addVersionMojo.checkVersion();
//        addVersionMojo.foreach(new File("E:\\tengxunketang\\fengzai-plugin\\src\\main"));
//        File file = new File("E:\\tengxunketang\\fengzai-plugin\\src\\main\\java\\com\\fengzai\\h2.html");
//        File file1 = new File("h2.html");
//        if (file1.exists()) {
//            file1.delete();
//        }
//        boolean b = file.renameTo(file1);


    }
}
